package com.vteba.utils.serialize;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Currency;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.objenesis.strategy.StdInstantiatorStrategy;

public class KryoPooledObjectFactory extends BasePooledObjectFactory<Kryo> {
	
	private List<Class<?>> classList;
	
	public KryoPooledObjectFactory(List<Class<?>> classList) {
		super();
		this.classList = classList;
	}

	@Override
	public Kryo create() throws Exception {
		Kryo kryo = new Kryo();
		kryo.setRegistrationRequired(true);
        kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
        
        kryo.register(Class.class);
        kryo.register(byte[].class);
        kryo.register(char[].class);
        kryo.register(short[].class);
        kryo.register(int[].class);
        kryo.register(long[].class);
        kryo.register(float[].class);
        kryo.register(double[].class);
        kryo.register(boolean[].class);
        kryo.register(String[].class);
        kryo.register(Object[].class);
        
        kryo.register(StringBuffer.class);
        kryo.register(StringBuilder.class);
        
        kryo.register(ArrayList.class);
        kryo.register(LinkedList.class);
        kryo.register(CopyOnWriteArrayList.class);
        
        kryo.register(HashMap.class);
        kryo.register(TreeMap.class);
        kryo.register(LinkedHashMap.class);
        kryo.register(ConcurrentHashMap.class);

        kryo.register(HashSet.class);
        kryo.register(TreeSet.class);
        kryo.register(LinkedHashSet.class);
        kryo.register(CopyOnWriteArraySet.class);

        kryo.register(BigInteger.class);
        kryo.register(BigDecimal.class);
        kryo.register(Currency.class);

        kryo.register(Date.class);
        kryo.register(java.sql.Date.class);
        
        if (classList != null) {
        	for (Class<?> clazz : classList) {
        		kryo.register(clazz);
        	}
        }
		return kryo;
	}

	@Override
	public PooledObject<Kryo> wrap(Kryo obj) {
		PooledObject<Kryo> pooledObject = new DefaultPooledObject<Kryo>(obj);
		return pooledObject;
	}

	public List<Class<?>> getClassList() {
		return classList;
	}

	public void setClassList(List<Class<?>> classList) {
		this.classList = classList;
	}

}
